home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 31
/
Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso
/
Aminet
/
dev
/
c
/
vbccm68ksrc.lha
/
vbcc
/
vlink
/
t_elf64.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-03-07
|
47KB
|
1,473 lines
/* $VER: vlink t_elf64.c V0.6a (19.12.98)
*
* This file is part of vlink, a portable linker for multiple
* object formats.
* Copyright (c) 1997-99 Frank Wille
*
* vlink is freeware and part of the portable and retargetable ANSI C
* compiler vbcc, copyright (c) 1995-99 by Volker Barthelmann.
* vlink may be freely redistributed as long as no modifications are
* made and nothing is charged for it. Non-commercial usage is allowed
* without any restrictions.
* EVERY PRODUCT OR PROGRAM DERIVED DIRECTLY FROM MY SOURCE MAY NOT BE
* SOLD COMMERCIALLY WITHOUT PERMISSION FROM THE AUTHOR.
*
*
* v0.6a (19.12.98) phx
* Support for little endian object file formats.
* ** t_elf64.c still doesn't work - don't activate it! **
* v0.6 (24.10.98) phx
* .sdata/.sbss and .sdata2/.sbss2 will always be combined.
* Each target defines their own base register section offsets.
* Linking with shared objects is possible. Creating them is
* a another story...
* ** t_elf64.c still doesn't work - don't activate it! **
* v0.5d (22.08.98) phx
* Faster memory allocation can be activated by #define FASTALLOC.
* ** t_elf64.c still doesn't work - don't activate it! **
* v0.5 (27.06.98) phx
* Target-specific linker symbol support: elf64_lnksym(),
* elf64_setlnksym().
* ** t_elf64.c still doesn't work - don't activate it! **
* v0.4 (05.06.98) phx
* New FFF targetlink(). Currently no meaning for ELF.
* ** t_elf64.c still doesn't work - don't activate it! **
* v0.0 (25.04.98) phx
* File created.
*/
#if defined(ELF64_ALPHA)
#define T_ELF64_C
#include "vlink.h"
#include "elf64.h"
#if defined(ELF64_ALPHA)
#include "rel_elfalpha.h"
#endif
#define ELF_VER 1
#ifdef ELF64_ALPHA
static int alpha64_identify(char*,uint8 *,unsigned long);
static void alpha64_readconv(struct GlobalVars *,struct LinkFile *);
static void alpha64_readELF(struct GlobalVars *,struct LinkFile *,uint8 *);
static unsigned long alpha64_secbase(struct GlobalVars *,char *);
static uint8 alpha64_cmpsecflags(uint8,uint8);
static struct Section *alpha64_bssdefault(struct ObjectUnit *);
static int alpha64_targetlink(struct GlobalVars *,struct LinkedSection *,
struct Section *);
static struct Symbol *alpha64_lnksym(struct GlobalVars *,struct Section *,
struct XReference *);
static void alpha64_setlnksym(struct GlobalVars *,struct Symbol *,
struct XReference *);
static void alpha64_relocs(struct GlobalVars *,uint8 *,struct ObjectUnit *,
struct Elf64_Shdr *);
static void alpha64_writeobject(struct GlobalVars *,FILE *);
static void alpha64_writeshared(struct GlobalVars *,FILE *);
static void alpha64_writeexec(struct GlobalVars *,FILE *);
static uint8 alpha64_getrel(uint8,char *,uint32);
struct FFFuncs fff_elf64alpha = {
"elf64alpha",
alpha64_identify,
alpha64_readconv,
alpha64_secbase,
alpha64_cmpsecflags,
alpha64_bssdefault,
alpha64_targetlink,
alpha64_lnksym,
alpha64_setlnksym,
alpha64_writeobject,
alpha64_writeshared,
alpha64_writeexec,
0x7ff0, /*@@@ I have no information */
NULL,
0 /* little endian */
};
#endif
/* small data sections */
static char *sdata = ".sdata";
static char *sbss = ".sbss";
static char *sdata2 = ".sdata2";
static char *sbss2 = ".sbss2";
static int elf64le_identify(struct FFFuncs *,char *,struct Elf64_Ehdr *,
unsigned long,unsigned char,unsigned char,
uint16,uint32);
static void elf64le_check_ar_type(struct FFFuncs *,char *,
struct Elf64_Ehdr *,unsigned char,
unsigned char,uint32,uint16,uint16,uint16);
static char *elf64le_shstrtab(struct LinkFile *,struct Elf64_Ehdr *);
static char *elf64le_strtab(struct LinkFile *,struct Elf64_Ehdr *,int);
static struct Elf64_Sym *elf64le_symtab(struct LinkFile *,
struct Elf64_Ehdr *,int);
static struct Elf64_Shdr *elf64le_shdr(struct LinkFile *lf,
struct Elf64_Ehdr *,uint16);
static void elf64le_section(uint8 *,struct ObjectUnit *,
struct Elf64_Shdr *,int);
static void elf64le_symbols(struct GlobalVars *,uint8 *,struct ObjectUnit *,
struct Elf64_Shdr *);
static void elf64le_reloc(struct GlobalVars *,struct Elf64_Ehdr *,
struct Section *,uint32,struct Elf64_Rela *,
bool,uint8);
static struct Section *elf64le_bssdefault(struct ObjectUnit *);
static int elf64_targetlink(struct GlobalVars *,struct LinkedSection *,
struct Section *);
static struct Symbol *elf64_lnksym(struct GlobalVars *,struct Section *,
struct XReference *);
static void elf64_setlnksym(struct GlobalVars *,struct Symbol *,
struct XReference *);
static void elf64le_header(FILE *,uint16,uint16,uint32,uint32,uint32,
uint32,uint16,uint16,uint16);
static void elf64le_writeshdrs(FILE *,uint32,uint32);
static void elf64le_stdsymtab(struct GlobalVars *,uint8,uint8);
static void elf64le_addsymlist(struct GlobalVars *,struct SymTabList *,
uint8,uint8);
static void elf64le_makeshdrs(struct GlobalVars *);
static void elf64le_addrelocs(struct GlobalVars *,
uint8 (*)(uint8,char *,uint32));
static void elf64le_makeshstrtab(void);
static void elf64le_makestrtab(void);
static void elf64le_makesymtab(uint32);
static struct ShdrNode *elf64le_addshdr(uint32,uint32,uint32,uint32,uint32,
uint32,uint32,uint32,uint32,uint32);
static uint32 elf64le_addsym(struct SymTabList *,char *,uint32,uint32,
uint8,uint8,uint16);
static uint32 elf64le_findsym(struct SymTabList *,char *,uint16);
static void elf64le_addrela(uint32,int32,uint32,uint8);
static void elf64_initlists(void);
static struct ShdrNode *elf64_newshdr(void);
static uint32 elf64_addshdrstr(char *);
static uint32 elf64_addstr(char *);
static uint32 elf64_addstrlist(struct StrTabList *,char *);
static uint8 elf64_getinfo(struct Symbol *);
static uint8 elf64_getbind(struct Symbol *);
static uint16 elf64_getshndx(struct Symbol *,uint8);
static void elf64_writesections(struct GlobalVars *,FILE *);
static void elf64_writestrtab(FILE *,struct StrTabList *);
static void elf64_writesymtab(FILE *,struct SymTabList *);
static void elf64_writerelocs(struct GlobalVars *,FILE *);
static char ELFid[4] = { /* identification for all ELF files */
0x7f,'E','L','F'
};
static struct ar_info ai; /* for scanning library archives */
static char *shstrtab; /* section header string table */
static char *nullstr = "";
/* static data required for output file generation */
static struct list shdrlist;
static struct list phdrlist;
static struct list relalist;
static struct SymTabList symlist;
static struct StrTabList shstrlist;
static struct StrTabList stringlist;
static uint32 shdrindex;
static uint32 symtabidx,shstrtabidx,strtabidx; /* indexes of Shdr names */
static uint32 elfoffset; /* current ELF file offset */
static int secsyms; /* offset to find section symbols by shndx */
/*****************************************************************/
/* Read ELF */
/*****************************************************************/
#ifdef ELF64_ALPHA
static int alpha64_identify(char *name,uint8 *p,unsigned long plen)
/* identify ELF-Alpha-64Bit-LittleEndian */
{
return (elf64le_identify(&fff_elf64alpha,name,(struct Elf64_Ehdr *)p,plen,
ELFCLASS64,ELFDATA2LSB,EM_ALPHA,ELF_VER));
}
static void alpha64_readconv(struct GlobalVars *gv,struct LinkFile *lf)
/* Read elf64alpha executable / object / shared obj. */
{
if (lf->type == ID_LIBARCH) {
if (ar_init(&ai,(char *)lf->data,lf->length,lf->filename)) {
while (ar_extract(&ai)) {
lf->objname